package com.zmn.oms.zmn.business.impl.pay;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.mq.constant.MqTopicConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.RedisManager;
import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.mcc.common.dto.staff.StaffDRO;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dro.orderpay.OrderPayResultDRO;
import com.zmn.oms.common.dto.*;
import com.zmn.oms.common.enums.RefundInitiateTypeEnum;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.bo.refund.RefundInitiateBO;
import com.zmn.oms.model.dto.order.pay.DuplicatePayRefundDTO;
import com.zmn.oms.model.dto.work.refund.RefundDTO;
import com.zmn.oms.model.dto.work.refund.RefundVoucherDTO;
import com.zmn.oms.model.dto.work.refund.VoucherDataDTO;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.model.entity.refund.OrderWorkRefundDetail;
import com.zmn.oms.model.entity.review.OmsOrderReview;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.refund.OrderWorkRefundDetailService;
import com.zmn.oms.services.interfaces.review.OmsOrderReviewService;
import com.zmn.oms.services.interfaces.tag.OrderTagService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.pay.OrderPayBService;
import com.zmn.oms.zmn.business.interfaces.work.orderpay.ZsOrderPayBService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.pay.common.dto.PayResultDTO;
import com.zmn.pay.gateway.common.model.dro.RefundResultDRO;
import com.zmn.tapi.common.dingtalk.FormComponentValueDIO;
import com.zmn.tapi.common.dingtalk.ProcessInstanceDIO;
import com.zmn.tapi.dubbo.interfaces.dingtalk.DingTalkAuditService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ：SongWeidong
 * @date ：2021/3/31 19:02
 * @description：支付明细
 */
@Service
@Slf4j
public class OrderPayBServiceImpl implements OrderPayBService {

    @Resource
    private OrderPayService orderPayService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private ZsOrderPayBService zsOrderPayBService;
    @Autowired
    private OrderWorkRefundDetailService refundDetailService;
    @Autowired
    private OmsOrderReviewService orderReviewService;
    @Resource
    private RedisManager redisManager;
    @Autowired
    private OrderPayBService orderPayBService;
    @Autowired
    private OrderTagService orderTagService;
    @Resource
    private ZmnMQSender zmnMQSender;
    @Autowired
    private OrderLogBService orderLogBService;

    @Value("${apply.approval.dtalk_id:140513}")
    private int APPLY_APPROVAL_DTALK_ID;

    @Reference(version = com.zmn.tapi.dubbo.DubboConsts.INTERFACE_VERSION, check = false)
    private DingTalkAuditService dingTalkAuditService;
    @Reference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    StaffListRemoteService staffListRemoteService;


    @Override
    public List<OrderPay> listOrderPayByOrderId(Long orderId) {
        return orderPayService.listOrderPayByOrderId(orderId);
    }

    @Override
    public void insertOrderPay(PayResultDTO payResultDTO) {
        OrderPay orderPay = BeanMapper.map(payResultDTO, OrderPay.class);
        orderPay.setPayOutTradeNo(payResultDTO.getTradNo());
        orderPay.setInnerTradeNo(payResultDTO.getOutTradNo());
        orderPay.setOrderId(payResultDTO.getBizId());
        orderPay.setPayChannelId(payResultDTO.getChannelId());
        processRequestDate(payResultDTO.getRequestData(), orderPay);
        orderPayService.insertOrderPay(orderPay);

    }

    @Transactional
    @Override
    public void insertOrderPay(OrderPayResultDRO orderPayResultDRO, Integer duplicateType) {
        // 系统重复-删除原来的
        if (Objects.equals(duplicateType, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_SYS)) {
            OrderPay orderPay = new OrderPay();
            orderPay.setOrderId(orderPayResultDRO.getOrderId());
            orderPay.setWorkId(orderPayResultDRO.getWorkId());
            orderPay.setAmountType(orderPayResultDRO.getAmountType());
            orderPay.setTradeType(PayConsts.PAY_TRADE_TYPE_INTIME);
            orderPayService.deleteByWorkIdAndAmountType(orderPay);
        }

        OrderPay orderPay = BeanMapper.map(orderPayResultDRO, OrderPay.class);
        orderPay.setOrderPayId(null);
        if (NumberUtil.isNotNullOrZero(orderPay.getLatitude())) {
            orderPay.setLatitude(orderPay.getLatitude() < 0 ? 0d : orderPay.getLatitude());
        }
        if (NumberUtil.isNotNullOrZero(orderPay.getLongitude())) {
            orderPay.setLongitude(orderPay.getLongitude() < 0 ? 0d : orderPay.getLongitude());
        }

        // 业务重复-标记为重复支付
        if (Objects.equals(duplicateType, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
            orderPay.setDuplicate(GlobalConsts.YES);

            // 重复支付处理
            DuplicatePayRefundDTO dto = BeanMapper.map(orderPayResultDRO, DuplicatePayRefundDTO.class);
            dto.setOrderPay(orderPay);
            dto.setDuplicateType(OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ);
            String key = "pay-duplicate-" + orderPayResultDRO.getWorkId();
            String message = JSON.toJSONString(dto);
            zmnMQSender.send(MqTopicConsts.ZMN_TOPIC_OMS, OmsMqTagConsts.ZMN_TOPIC_OMS_ORDER_PAY_DUPLICATE_TAG, key, message);

        }
        String operator = StringUtils.defaultString(orderPayResultDRO.getOperator(), "系统");
        orderPay.setUpdater(operator);
        orderPay.setCreater(operator);
        orderPay.setCreateTime(DateUtil.getNow());
        orderPay.setUpdateTime(DateUtil.getNow());
        orderPayService.insertOrderPay(orderPay);
    }

    /**
     * 重复支付退款
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DUPLICATE_PAY_REFUND_AUDIT_RESULT, beforeProceed = false)
    @Override
    public void duplicatePayRefund(DuplicatePayRefundDTO dto) {
        try {
            OmsOperator operator = new OmsOperator();
            operator.setOperatorPlat(dto.getOperatorPlat());
            operator.setOperatorType(dto.getOperatorType());
            operator.setOperatorId(dto.getOperatorId());
            operator.setOperator(dto.getOperator());

            RefundInitiateBO refundInitiateBO = RefundInitiateBO.builder()
                    .refundInitiateType(RefundInitiateTypeEnum.REFUND_DUPLICATE.getType())
                    .refundType(OrderConsts.ORDER_REFUND_TYPE_ONLINE)
                    .refundAmount(dto.getAmount())
                    .payTargetChannelId(dto.getPayTargetChannelId())
                    .refundOrderWork(dto.getOrderWork())
                    .orderPayList(Lists.newArrayList(dto.getOrderPay()))
                    .operator(operator)
                    .build();

            zsOrderPayBService.payRefundAmount(refundInitiateBO);
        } catch (OmsBaseException e) {
            e.printStackTrace();
            log.info("重复支付退款失败：【{}】", e.getMessage());
        }
    }

    /**
     * 重复支付退款审批
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean duplicatePayRefundApprove(DuplicatePayRefundDTO dto) {

        // 重复支付审核日志
        OrderLog orderLog = orderLogBService.generateOrderLog(dto.getOrderId(), dto.getWorkId(),
                OrderLogConsts.ORDER_LOG_TYPE_DUPLICATE_PAY_REFUND_AUDIT,
                "系统", 1L, GlobalConsts.OPERATE_USER_TYPE_SYSTEM, null, null);

        // 查询贾小兵-140513的钉钉id
        // 测试环境暂时用魏春琳-15140258
        ResponseDTO<StaffDRO> staff = staffListRemoteService.getStaff(APPLY_APPROVAL_DTALK_ID);
        log.info("[{}]查询员工钉钉id出参：【{}】", dto.getOrderId(), JSON.toJSONString(staff));
        if (!staff.isSuccess() && Objects.isNull(staff.getData())) {
            orderLog.setContent("发起钉钉审核失败:审核人配置失效");
            orderLogBService.save(orderLog);
            return false;
        }

        String companyName = NumberUtil.isNullOrZero(dto.getOrderWork().getCompanyId()) ? "无公司" : dto.getOrderWork().getCompanyName();

        List<FormComponentValueDIO> formComponentValueDIOS = Lists.newArrayList(
                FormComponentValueDIO.builder()
                        .name("服务子公司")
                        .value(companyName)
                        .build(),
                FormComponentValueDIO.builder()
                        .name("工单号")
                        .value(String.valueOf(dto.getOrderWork().getWorkId()))
                        .build(),
                FormComponentValueDIO.builder()
                        .name("退款金额（元）")
                        .value(NumberUtil.convertMoneyToYuan2(dto.getAmount()))
                        .build(),
                FormComponentValueDIO.builder()
                        .name("支付流水号")
                        .value(dto.getPayOutTradeNo())
                        .build()
        );

        ProcessInstanceDIO dio = ProcessInstanceDIO.builder()
                .originatorUserId(staff.getData().getDTalkId())
                .processCode("PROC-484E59C7-F042-4EAD-BA96-18E1308D9561")
                .componentValues(formComponentValueDIOS)
                .build();
        log.info("[{}]重复支付退款审批退款入参：【{}】", dto.getOrderId(), dio);
        ResponseDTO<String> responseDTO = dingTalkAuditService.createProcessInstance(dio);
        log.info("[{}]重复支付退款审批退款出参：【{}】", dto.getOrderId(), responseDTO);


        boolean isSuccess = responseDTO.isSuccess() && StringUtil.isNotBlank(responseDTO.getData());
        if (!isSuccess) {
            orderLog.setContent(String.format("发起钉钉审核失败:消息未发送给审核人"));
            orderLogBService.save(orderLog);
            return false;
        }

        // 生成审批记录
        OmsOrderReview omsOrderReview = new OmsOrderReview();
        Date now = DateUtil.getNow();
        omsOrderReview.setOrderId(dto.getOrderWork().getOrderId());
        omsOrderReview.setWorkId(dto.getOrderWork().getWorkId());
        omsOrderReview.setReviewType(OrderConsts.OMS_ORDER_REVIEW_DUPLICATE_PAY_REFUND);
        omsOrderReview.setReviewStatus(OrderConsts.OMS_ORDER_REVIEW_STATUS_CHECK);
        omsOrderReview.setReviewData(JSON.toJSONString(dto));
        omsOrderReview.setProcessInstanceId(responseDTO.getData());
        omsOrderReview.setCreater(dto.getOperator());
        omsOrderReview.setCreateTime(now);
        omsOrderReview.setUpdater(dto.getOperator());
        omsOrderReview.setUpdateTime(now);
        orderReviewService.insertOmsOrderReview(omsOrderReview);

        String key = String.format(RedisKeyConsts.ORDER_REVIEW_CODE_KEY, responseDTO.getData());
        RedisReviewDTO refundReviewDTO = new RedisReviewDTO();
        refundReviewDTO.setOrderId(dto.getOrderWork().getOrderId());
        refundReviewDTO.setWorkId(dto.getOrderWork().getWorkId());
        refundReviewDTO.setReviewType(OrderConsts.OMS_ORDER_REVIEW_DUPLICATE_PAY_REFUND);
        // 30天
        redisManager.setex(key, JSON.toJSONString(refundReviewDTO), 86400 * 30);

        // 保存日志
        orderLog.setContent(String.format("待%s内勤审核(钉钉)，退款金额：%s",
                companyName, NumberUtil.convertMoneyToYuan2(dto.getAmount())));
        orderLogBService.save(orderLog);

        return true;
    }


    /**
     * 新增原路返回退款记录
     *
     * @param refundResultDRO  退款结果
     * @param refundRequestDTO 退款业务数据
     */
    @Override
    public void insertRefundOrderPay(RefundResultDRO refundResultDRO, OmsRefundRequestDTO refundRequestDTO) {
        String lockKey = String.format("%s", refundRequestDTO.getWorkId());
        DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);

        try {
            if (lock.tryLock()) {
                List<OrderPay> orderPays = orderPayService.listOrderPayByOrderIdAndWorkId(refundRequestDTO.getOrderId(), refundRequestDTO.getWorkId());
                if (StringUtil.isNotBlank(refundResultDRO.getRefundInnerTradeNo())) {
                    boolean existsRefund = orderPays.stream()
                            .filter(e -> StringUtil.isNotBlank(e.getInnerTradeNo()) && Objects.equals(e.getTradeType(), PayConsts.PAY_TRADE_TYPE_REFUND))
                            .anyMatch(e -> Objects.equals(e.getInnerTradeNo(), refundResultDRO.getRefundInnerTradeNo()));
                    if (existsRefund) {
                        log.error("{}已存在退款记录{}，插入重复数据{}", refundRequestDTO.getWorkId(), JSON.toJSONString(orderPays), refundResultDRO);
                        return;
                    }
                }
                OrderPay refundPay = new OrderPay();
                refundPay.setOrderId(refundRequestDTO.getOrderId());
                refundPay.setWorkId(refundRequestDTO.getWorkId());
                refundPay.setAmountType(0);
                refundPay.setTradeType(PayConsts.PAY_TRADE_TYPE_REFUND);
                refundPay.setRefundType(refundRequestDTO.getRefundType());
                refundPay.setPayStatus(refundResultDRO.getStatus());
                refundPay.setPayChannelId(refundResultDRO.getChannelId());
                refundPay.setPayType(refundResultDRO.getPayType());
                refundPay.setInnerTradeNo(refundResultDRO.getRefundInnerTradeNo());
                refundPay.setPayOutTradeNo(refundResultDRO.getRefundOutTradeNo());
                refundPay.setPayTime(refundResultDRO.getRefundTime());
                refundPay.setAmount(refundResultDRO.getRefundAmount());
                if (Objects.nonNull(refundRequestDTO.getDuplicate())) {
                    refundPay.setDuplicate(refundRequestDTO.getDuplicate());
                }
                refundPay.setCreater(StringUtils.defaultString(refundRequestDTO.getOperator(), "系统"));
                refundPay.setUpdater(StringUtils.defaultString(refundRequestDTO.getOperator(), "系统"));
                refundPay.setCreateTime(DateUtil.getNow());
                refundPay.setUpdateTime(DateUtil.getNow());
                orderPayService.insertOrderPay(refundPay);
            }
        } catch (Exception e) {
            log.error("订单退款插入异常:" + e.getMessage(), e);
        } finally {
            lock.unlock();
        }
    }

    // 处理拓展数据
    private void processRequestDate(String requestData, OrderPay orderPay) {
        OmsPayRequestDTO omsPayRequestDTO = JSON.parseObject(requestData, OmsPayRequestDTO.class);
        orderPay.setOrderId(omsPayRequestDTO.getOrderId());
        orderPay.setWorkId(omsPayRequestDTO.getWorkId());
        orderPay.setPayerId(omsPayRequestDTO.getOperatorId());
        orderPay.setPayerType(omsPayRequestDTO.getOperatorType());
        orderPay.setLongitude(omsPayRequestDTO.getLongitude());
        orderPay.setLatitude(omsPayRequestDTO.getLatitude());
        orderPay.setUpdater(StringUtils.defaultString(omsPayRequestDTO.getOperator(), "1"));
        orderPay.setCreater(StringUtils.defaultString(omsPayRequestDTO.getOperator(), "1"));
        orderPay.setCreateTime(DateUtil.getNow());
        orderPay.setUpdateTime(DateUtil.getNow());
    }


    /**
     * 保存线下退款
     *
     * @param refundDTO
     */
    public void saveOfflineRefund(Long orderId, Long workId, Integer refundStatus, RefundDTO refundDTO) {
        OrderPay orderPay = new OrderPay();
        orderPay.setOrderId(orderId);
        orderPay.setWorkId(workId);
        orderPay.setAmountType(0);
        orderPay.setTradeType(PayConsts.PAY_TRADE_TYPE_REFUND);
        orderPay.setRefundType(refundDTO.getRefundType());
        orderPay.setPayStatus(refundStatus);
        orderPay.setPayChannelId(PayConsts.PAY_CHANNEL_PLATFORM_OFFLINE);
        orderPay.setPayType(PayConsts.PAY_TYPE_MANUAL);
        orderPay.setPayTargetChannelId(refundDTO.getPayTargetChannelId());
        orderPay.setPayTargetType(PayConsts.PAY_TYPE_MANUAL);
        orderPay.setPayTime(new Date());
        orderPay.setPayeeType(com.zmn.consts.GlobalConsts.OPERATE_USER_TYPE_USER);
        orderPay.setPayeeId(0L);
        orderPay.setPayeeAccountId(0L);
        orderPay.setPayeeThirdAccount(refundDTO.getPayeeThirdAccount());
        orderPay.setPayeeThirdAccountName(refundDTO.getPayeeThirdAccountName());
        orderPay.setPayeeThirdAccountBank(refundDTO.getPayeeThirdAccountBank());
        orderPay.setAmount(refundDTO.getRefundAmount());
        orderPay.setCreater(StringUtils.defaultIfBlank(refundDTO.getOperator(), "系统"));
        orderPay.setUpdater(StringUtils.defaultIfBlank(refundDTO.getOperator(), "系统"));
        Date now = DateUtil.getNow();
        orderPay.setCreateTime(now);
        orderPay.setUpdateTime(now);
        orderPayService.insertOrderPay(orderPay);
    }

    @Override
    @Transactional
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_REFUND_VOUCHER, beforeProceed = false)
    public void saveRefundVoucher(RefundVoucherDTO refundVoucherDTO) throws OmsBaseException {
        OrderPay refundPay = orderPayService.findOrderPayByKey(refundVoucherDTO.getOrderId(), refundVoucherDTO.getOrderPayId());
        if (Objects.isNull(refundPay)) {
            ResultDTO.fail("退款信息不存在");
        }

        // 更新凭证
        OrderPay orderPay = new OrderPay();
        orderPay.setOrderId(refundPay.getOrderId());
        orderPay.setOrderPayId(refundPay.getOrderPayId());
        orderPay.setRefundImageData(JSON.toJSONString(refundVoucherDTO.getRefundVoucherData()));
        orderPay.setPayerThirdAccount(refundVoucherDTO.getPayerThirdAccount());
        orderPay.setPayerThirdAccountBank(refundVoucherDTO.getPayerThirdAccountBank());
        orderPay.setUpdater(refundVoucherDTO.getOperator());
        orderPay.setUpdateTime(DateUtil.getNow());
        orderPayService.updateByPrimaryKeySelective(orderPay);

        if (StringUtil.isBlank(refundPay.getRefundImageData())) {
            // 调用支付
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(refundVoucherDTO.getOrderId(), refundVoucherDTO.getWorkId());
            OmsOperator omsOperator = new OmsOperator();
//            refundDTO.setRefundVoucherData(refundVoucherDTO.getRefundVoucherData());
            omsOperator.setOperatorPlat(refundVoucherDTO.getOperatorPlat());
            omsOperator.setOperatorType(refundVoucherDTO.getOperatorType());
            omsOperator.setOperatorId(refundVoucherDTO.getOperatorId());
            omsOperator.setOperator(refundVoucherDTO.getOperator());
            List<OrderPay> orderPayList = orderPayBService.listOrderPayByOrderId(orderWork.getOrderId());

            RefundInitiateBO refundInitiateBO = RefundInitiateBO.builder()
                    .refundInitiateType(RefundInitiateTypeEnum.REFUND_ORDER.getType())
                    .refundType(refundPay.getRefundType())
                    .refundAmount(refundPay.getAmount())
                    .refundOrderWork(orderWork)
                    .orderPayId(refundPay.getOrderPayId())
                    .payTargetChannelId(refundPay.getPayTargetChannelId())
                    .payeeThirdAccount(refundPay.getPayeeThirdAccount())
                    .payeeThirdAccountName(refundPay.getPayeeThirdAccountName())
                    .payeeThirdAccountBank(refundPay.getPayeeThirdAccountBank())
                    .operator(omsOperator)
                    .orderPayList(orderPayList)
                    .build();
            zsOrderPayBService.payRefundAmount(refundInitiateBO);
        }

        // refundDetail数据
        OrderWorkRefundDetail refundDetailDB = refundDetailService.findOrderWorkRefundDetailByOrderIdAndWorkId(refundVoucherDTO.getOrderId(), refundVoucherDTO.getWorkId());
        OrderWorkRefundDetail detail = new OrderWorkRefundDetail();
        // 第一次打款
        if (StringUtil.isBlank(refundPay.getRefundImageData())) {
            detail.setRemitPeople(refundVoucherDTO.getOperatorId());
        }
        detail.setRefundPoundage(refundVoucherDTO.getRefundPoundage());
        detail.setPayerThirdAccount(refundVoucherDTO.getPayerThirdAccount());
        detail.setPayerThirdAccountBank(refundVoucherDTO.getPayerThirdAccountBank());
        String refundVoucherNos = refundVoucherDTO.getRefundVoucherData()
                .stream()
                .map(VoucherDataDTO::getRefundNo)
                .collect(Collectors.joining(","));
        detail.setRefundVoucherNo(refundVoucherNos);
        detail.setRefundVoucherRemark(refundVoucherDTO.getRefundVoucherRemark());
        detail.setOrderId(refundVoucherDTO.getOrderId());
        if (Objects.isNull(refundDetailDB)) {
            detail.setWorkId(refundVoucherDTO.getWorkId());
            detail.setRefundType(refundPay.getRefundType());
            detail.setRefundPath(refundPay.getPayTargetChannelId());
            detail.setPayeeThirdAccount(refundPay.getPayeeThirdAccount());
            detail.setPayeeThirdAccountName(refundPay.getPayeeThirdAccountName());
            detail.setPayeeThirdAccountBank(refundPay.getPayeeThirdAccountBank());
            refundDetailService.insertOrderWorkRefundDetail(detail);
        } else {
            detail.setRefundDetailId(refundDetailDB.getRefundDetailId());
            refundDetailService.updateByDetailId(detail);
        }

    }

    /**
     * 定金和进度款重复支付判断
     *
     * @param orderPayResultDRO
     * @return
     */
    @Override
    public Integer depositAndProgressAmountDuplicationOrderPay(OrderPayResultDRO orderPayResultDRO) {
        Integer amountType = orderPayResultDRO.getAmountType();
        if (!(Objects.equals(amountType, OrderPayConsts.ORDER_PAY_DEPOSIT) || Objects.equals(amountType, OrderPayConsts.ORDER_PAY_PROGRESS))) {
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
        }

        Integer count = orderPayService.countByWorkIdAndAmountType(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId(),
                amountType, PayConsts.PAY_TRADE_TYPE_INTIME);
        // 无支付重复
        if (count == 0) {
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
        }

        String amountTypeName = OrderPayConsts.getAmountTypeName(amountType);
        // 未支付
        List<OrderPay> orderPayList = orderPayService.listOrderPayByOrderIdAndWorkIdAndAmountTypeMasterSrc(orderPayResultDRO.getOrderId(),
                orderPayResultDRO.getWorkId(), amountType);
        boolean exitsPay = orderPayList.stream().anyMatch(e -> Objects.equals(orderPayResultDRO.getPayOutTradeNo(), e.getPayOutTradeNo()));
        if (exitsPay) {
            log.info("{}--系统重复，发现相同流水号，本次orderPayResultDRO==>{}，已有OrderPay==>{}", amountTypeName, orderPayResultDRO, JSON.toJSONString(orderPayList));
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_SYS;
        } else {
            Long orderPayId = orderPayResultDRO.getOrderPayId();
            if (NumberUtil.isNotNullOrZero(orderPayId)) {
                OrderPay orderPay = orderPayService.findAllOrderPayByKeySrcMaster(orderPayResultDRO.getOrderId(), orderPayId);
                if (Objects.equals(orderPay.getPayStatus(), PayConsts.PAY_STATUS_DONE)) {
                    log.info("{}--业务重复，有支付id，并且当前这笔已经支付。发现不同流水号，本次orderPayResultDRO==>{}，已有OrderPay==>{}", amountTypeName, orderPayResultDRO, JSON.toJSONString(orderPayList));
                    return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ;
                } else {
                    return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
                }
            } else {
                log.info("{}--业务重复，无支付id，发现不同流水号，本次orderPayResultDRO==>{}，已有OrderPay==>{}", amountTypeName, orderPayResultDRO, JSON.toJSONString(orderPayList));
                return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ;
            }
        }
    }

    /**
     * 平台代收和工程师收款重复支付判断
     *
     * @param orderPayResultDRO
     * @return
     */
    @Override
    public Integer prepayAndMasterAmountDuplicationOrderPay(OrderPayResultDRO orderPayResultDRO) {
        Integer amountType = orderPayResultDRO.getAmountType();
        if (!(Objects.equals(amountType, OrderPayConsts.ORDER_PAY_PREPAY) || Objects.equals(amountType, OrderPayConsts.ORDER_PAY_MASTER))) {
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
        }

        Integer count = orderPayService.countByWorkIdAndAmountType(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId(),
                amountType, PayConsts.PAY_TRADE_TYPE_INTIME);
        // 无支付重复
        if (count == 0) {
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
        }

        String amountTypeName = OrderPayConsts.getAmountTypeName(amountType);
        // 未支付
        List<OrderPay> orderPayList = orderPayService.listOrderPayByOrderIdAndWorkIdAndAmountTypeMasterSrc(orderPayResultDRO.getOrderId(),
                orderPayResultDRO.getWorkId(), amountType);
        boolean exitsPay = orderPayList.stream().anyMatch(e -> Objects.equals(orderPayResultDRO.getPayOutTradeNo(), e.getPayOutTradeNo()));
        if (exitsPay) {
            log.info("{}--系统重复，发现相同流水号，本次orderPayResultDRO==>{}，已有OrderPay==>{}", amountTypeName, orderPayResultDRO, JSON.toJSONString(orderPayList));
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_SYS;
        } else {
            log.info("{}--业务重复，发现不相同流水号，本次orderPayResultDRO==>{}，已有OrderPay==>{}", amountTypeName, orderPayResultDRO, JSON.toJSONString(orderPayList));
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ;
        }
    }

    /**
     * 优惠和渠道收款重复支付
     *
     * @param orderPayResultDRO
     * @return
     */
    @Override
    public Integer channelPrepayAndDiscountAmountDuplicationOrderPay(OrderPayResultDRO orderPayResultDRO) {
        Integer amountType = orderPayResultDRO.getAmountType();
        if (!(Objects.equals(amountType, OrderPayConsts.ORDER_PAY_CHANNEL_PREPAY) || Objects.equals(amountType, OrderPayConsts.ORDER_PAY_DISCOUNT))) {
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
        }

        Integer count = orderPayService.countByWorkIdAndAmountType(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId(),
                amountType, PayConsts.PAY_TRADE_TYPE_INTIME);
        // 无支付重复
        if (count == 0) {
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE;
        } else {
            String amountTypeName = OrderPayConsts.getAmountTypeName(amountType);
            log.info("{}--系统重复，发现相同流水号，本次orderPayResultDRO==>{}，已有OrderPayCount==>{}", amountTypeName, orderPayResultDRO, count);
            return OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_SYS;
        }

    }
}
